package nl.zuiderfestival.raydance.view.particle;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JPanel;

import nl.zuiderfestival.raydance.view.canvas.ZoneDisplay;
import TUIO.TuioCursor;
import TUIO.TuioListener;
import TUIO.TuioObject;
import TUIO.TuioTime;

public class TuioParticleDisplay extends ZoneDisplay implements TuioListener, Runnable {

	private static final Color PARTICLE_COLOR = Color.blue;
	private static final int PARTICLE_LIFE = 60;
	private static final int PARTICLE_SIZE = 12;

	private Thread thread;
	
	private ArrayList<Particle> particles = new ArrayList<Particle>(500);

	private JPanel render;

	private int size;
	private boolean displayMovementEnabled;
	
	public TuioParticleDisplay(int size) {
		super(size);
		this.size = size;
		
		render = new JPanel();
		displayMovementEnabled = false;

		Dimension dimension = new Dimension(size, size);
		setPreferredSize(dimension);
		render.setPreferredSize(dimension);
		add(render);
	}

	private static final long serialVersionUID = 1L;

	public void start() {
		thread = new Thread(this);
		thread.start();
	}
	
	public void stop() {
		thread = null;
	}
	
	public void toggleDisplayMovementEnabled() {
		this.displayMovementEnabled = !displayMovementEnabled;
		
		if (!displayMovementEnabled) {
			particles.clear();
			repaint();
		}
	}
	
	public void addTuioCursor(TuioCursor cursor) {
		if (displayMovementEnabled) {
			addParticle((int)(cursor.getX()*size), (int)(cursor.getY()*size));
		}
	}

	public void updateTuioCursor(TuioCursor cursor) {
		if (displayMovementEnabled) {
			addParticle((int)(cursor.getX()*size), (int)(cursor.getY()*size));
		}
	}
	
	public void run() {
		Thread myThread = Thread.currentThread();
		while(myThread.equals(thread)) {
			
			if (displayMovementEnabled) {
				update();
				repaint();
			}

			try {
				Thread.sleep(1000/60);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void addParticle(int x, int y){
		particles.add(new Particle(x,y,PARTICLE_SIZE,PARTICLE_LIFE,PARTICLE_COLOR));
	}

	private void update(){
		Iterator<Particle> iterator = particles.iterator();
		while (iterator.hasNext()) {
			Particle p = iterator.next();
			if (p.update()) {
				iterator.remove();
			}
		}
	}

	@Override
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
		g2d.fillRect(0, 0, render.getWidth(), render.getHeight());

		renderParticles(g2d);

		g2d.dispose();
	}

	private void renderParticles(Graphics2D g2d){
		Iterator<Particle> iterator = particles.iterator();
		while (iterator.hasNext()) {
			Particle p = iterator.next();
			p.render(g2d);
		}
	}

	public void removeTuioCursor(TuioCursor cursor) { }
	public void refresh(TuioTime time) {}
	public void updateTuioObject(TuioObject object) { }
	public void removeTuioObject(TuioObject object) { }
	public void addTuioObject(TuioObject object) { }

}
